﻿#include "uiscadacfgtool.h"
#include "ui_uiscadacfgtool.h"

#include <QMessageBox>
#include <QFileDialog>
#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include <QTextEdit>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlRecord>
#include <QtSql/QSqlError>
#include <QProgressDialog>
#include <QDateTime>

#include "stringdb.h"
#include "stringlistdb.h"

QString getAbsolutePath( const QString& path,const bool& raw ){
    QString pjt = UiScadaCfgTool::ins()->getFileName();
    if( pjt.isEmpty() || path.isEmpty() || raw )
        return path;

    QFileInfo fi(pjt);
    return fi.dir().absoluteFilePath(path);
}

QString getRelativePath( const QString& path ){
    QString pjt = UiScadaCfgTool::ins()->getFileName();
    if( pjt.isEmpty() || path.isEmpty() )
        return path;

    QFileInfo fi(pjt);
    return fi.dir().relativeFilePath(path);
}

UiScadaCfgTool::UiScadaCfgTool(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::UiScadaCfgTool)
{
    ui->setupUi(this);
    m_devices.append( dynamic_cast<UiDeviceInfo*>(ui->tabWidget_devices->widget(0)));
    connect(m_devices.at(0),SIGNAL(descChanged()),this,SLOT(deviceDescChanged()));

    connect(ui->pushButton_open,SIGNAL(clicked()),this,SLOT(open()));
    connect(ui->pushButton_save,SIGNAL(clicked()),this,SLOT(save()));
    connect(ui->pushButton_saveAs,SIGNAL(clicked()),this,SLOT(saveAs()));
    connect(ui->pushButton_exportSqlite,SIGNAL(clicked()),this,SLOT(genAndExport()));
    connect(ui->pushButton_del,SIGNAL(clicked()),this,SLOT(delDevice()));

    connect(ui->pushButton_about,SIGNAL(clicked()),this,SLOT(help()));

    connect(ui->tabWidget_devices,SIGNAL(tabCloseRequested(int)),this,SLOT(delDevice(int)));
    connect(ui->tabWidget_logics,SIGNAL(tabCloseRequested(int)),this,SLOT(delDevice(int)));
}

UiScadaCfgTool* UiScadaCfgTool::ins(){
    static UiScadaCfgTool i;
    return &i;
}

UiScadaCfgTool::~UiScadaCfgTool()
{
    delete ui;
}

void UiScadaCfgTool::open(){
    if( ui->tabWidget_devices->count()!=0 ){
        if( QMessageBox::Yes!=QMessageBox::warning(this,QString::fromUtf8("注意"),QString::fromUtf8("有配置的设备信息将会被关闭，确定?"),QMessageBox::Yes,QMessageBox::Cancel) )
                return;
        while( ui->tabWidget_devices->count()>0 )
            ui->tabWidget_devices->removeTab(0);
        m_devices.clear();

        while( ui->tabWidget_logics->count()>0 )
            ui->tabWidget_logics->removeTab(0);
        m_logicDevices.clear();

        setWindowTitle(tr("None"));
    }

    QString name = QFileDialog::getOpenFileName(this,QString::fromUtf8("工程文件"),"",tr("DM Config File (*.dmc)"));
    if( name.isEmpty() )
        return;

    // 设备名%描述%状态量%离散量%测量量%累计量%远控%参数
    //
    QFile inFile(name);

    if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
        QMessageBox::warning(this,tr("Error"),tr("open file %1 fail.").arg( name ));
        return;
    }

    m_fileName = name;
    setWindowTitle( name );

    QTextStream inStream(&inFile);
    inStream.setCodec("UTF-8");

    while( !inStream.atEnd() ){
        QStringList items = inStream.readLine().split('%');
        if( items.count()==9 ){
            ui->tabWidget_type->setCurrentIndex(0);
            addDevice();
            UiDeviceInfo* device = m_devices.last();
            ui->tabWidget_devices->setTabText(m_devices.count()-1, QString::number(m_devices.count())+QString::fromUtf8(items.at(1).toStdString().c_str()) );

            int i = 0;
            device->setName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setDesc( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setStatusCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setDiscreteCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setMeasureCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setCumulantCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setRemoteCtlCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setParameterCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
            device->setActionCfgFileName( QString::fromUtf8(items.at(i++).toStdString().c_str()) );
        }else if( items.count()==10 && items.at(0)=="#" ){
            ui->tabWidget_type->setCurrentIndex(1);

            addDevice();
            UiLogicDevice* device = m_logicDevices.last();
            ui->tabWidget_logics->setTabText(m_logicDevices.count()-1,QString::number(m_logicDevices.count())+QString::fromUtf8(items.at(2).toStdString().c_str()));

            int i = 1;
            device->setName(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setDesc(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setStatusMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setDiscreteMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setMeasureMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setCumulantMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setRemoteCtlMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setParameterMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
            device->setActionMapFile(QString::fromUtf8(items.at(i++).toStdString().c_str()));
        }else{
            QMessageBox::warning(this,tr("Error"),tr("The Format is unknow of the configure file"));
            return;
        }
    }
}

void UiScadaCfgTool::save(){
    if( m_fileName.isEmpty() )
        saveAs();
    else{
        QFile outFile(m_fileName);
        if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
            return;
        }

        QTextStream outStream(&outFile);
        outStream.setCodec("UTF-8");

        for( int i=0;i<ui->tabWidget_devices->count();++i ){
            const UiDeviceInfo* device = m_devices.at(i);
            outStream<<device->getName().toUtf8().constData()<<"%"
                    <<device->getDesc().toUtf8().constData()<<"%"
                   <<device->getStatusCfgFileName(true).toUtf8().constData()<<"%"
                     <<device->getDiscreteCfgFileName(true).toUtf8().constData()<<"%"
                   <<device->getMeasureCfgFileName(true).toUtf8().constData()<<"%"
                     <<device->getCumulantCfgFileName(true).toUtf8().constData()<<"%"
                   <<device->getRemoteCtlCfgFileName(true).toUtf8().constData()<<"%"
                  <<device->getParameterCfgFileName(true).toUtf8().constData()<<"%"
                 <<device->getActionCfgFileName(true).toUtf8().constData()<<"\n";
        }

        for( int i=0;i<ui->tabWidget_logics->count();++i ){
            const UiLogicDevice* device = m_logicDevices.at(i);
            outStream<<"#%" <<device->getName().toUtf8().constData()<<"%"
                    <<device->getDesc().toUtf8().constData()<<"%"
                   <<device->getStatusMapFile(true).toUtf8().constData()<<"%"
                     <<device->getDiscreteMapFile(true).toUtf8().constData()<<"%"
                   <<device->getMeasureMapFile(true).toUtf8().constData()<<"%"
                     <<device->getCumulantMapFile(true).toUtf8().constData()<<"%"
                   <<device->getRemoteCtlMapFile(true).toUtf8().constData()<<"%"
                  <<device->getParameterMapFile(true).toUtf8().constData()<<"%"
                 <<device->getActionMapFile(true).toUtf8().constData()<<"\n";
        }
    }
}

void UiScadaCfgTool::saveAs(){
    QString name = QFileDialog::getSaveFileName(this,QString::fromUtf8("工程文件"),"",tr("DM Config File (*.dmc)"));
    if( name.isEmpty() )
        return;

    m_fileName = name;
    setWindowTitle(name);
    save();
}

void UiScadaCfgTool::genAndExport(){
    if( !exportCheck() )
        return;

    int pg_step = 0;

    QFileInfo f(m_fileName);
    QString dir = QFileDialog::getExistingDirectory(this,tr("Special Directory"),f.path());
    if( !dir.isEmpty() ){
        if( ui->tabWidget_devices->count()<=0 ){
            QMessageBox::warning(this,tr("Attition"),tr("At leaste One device must be configured"));
        }else{
            // 计算总进度
            int lineCnt;
            for( int i=0;i<m_devices.count();++i ){
                lineCnt = getFileLines(m_devices.at(i)->getStatusCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的状态量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_devices.at(i)->getDiscreteCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的离散量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_devices.at(i)->getMeasureCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的测量量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_devices.at(i)->getCumulantCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的累计量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;


                lineCnt = getFileLines(m_devices.at(i)->getRemoteCtlCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的远控配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;


                lineCnt = getFileLines(m_devices.at(i)->getParameterCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的参数配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;


                lineCnt = getFileLines(m_devices.at(i)->getActionCfgFileName(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的动作配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;
            }

            for( int i=0;i<m_logicDevices.size();++i ){
                lineCnt = getFileLines(m_logicDevices.at(i)->getStatusMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的状态量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_logicDevices.at(i)->getDiscreteMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的离散量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_logicDevices.at(i)->getMeasureMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的测量量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_logicDevices.at(i)->getCumulantMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的累计量配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_logicDevices.at(i)->getRemoteCtlMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的远控配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_logicDevices.at(i)->getParameterMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的参数配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;

                lineCnt = getFileLines(m_logicDevices.at(i)->getActionMapFile(false));
                if( lineCnt<0 ){
                    QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的动作配置文件打开失败").arg( QString::number(i+1)));
                    return;
                }

                pg_step += lineCnt;
            }

            // 设置进度条
            QProgressDialog pg("Gen Cfgs","Stop",0,pg_step,this);
            pg.setModal(true);

            connect(&pg,SIGNAL(canceled()),this,SLOT(onCancel()));

            pg_step = 0;

            CStringDb deviceDb;
            CStringDb statusDescDb;
            CStringListDb discreteDescDb;
            CStringDb remoteCtlDescDb;
            CStringDb actionDescDb;

            CStringDb logicDb;
#ifdef _WIN32
            dir.append('\\');
#else
            dir.append("/");
#endif
            QFile outFile;
            QTextStream outStream;
            outStream.setCodec("UTF-8");

            QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE","dm_scada");
            db.setHostName("localhost");
            db.setDatabaseName(dir+"dm_scada.db3");
            if( !db.open() ){
                QMessageBox::warning(this,tr("warnning"),tr("Can not open sqlite db ")+dir+"dm_scada.db3");
            }

            QSqlQuery query(db);

            QString sql;
            QTextStream sqlStream(&sql);
            sqlStream.setCodec("UTF-8");

            for( int i=0;i<m_devices.count();++i ){
                deviceDb.findOrAdd(m_devices.at(i)->getName());
            }

            if( ui->checkBox_sysInfo->isChecked() )
                deviceDb.findOrAdd("sys");


            for( int i=0;i<m_logicDevices.count();++i ){
                logicDb.findOrAdd(m_logicDevices.at(i)->getName() );
            }

            if( !exportSqlite_createTables(query) )
                return;

            if( !exportSqlite_status(dir,pg,pg_step,query,deviceDb,statusDescDb) )
                return;

            if( !exportSqlite_discrete(dir,pg,pg_step,query,deviceDb,discreteDescDb) )
                return;

            if( !exportSqlite_measure(dir,pg,pg_step,query,deviceDb) )
                return;

            if( !exportSqlite_cumulant(dir,pg,pg_step,query,deviceDb) )
                return;

            if( !exportSqlite_remoteCtl(dir,pg,pg_step,query,deviceDb,remoteCtlDescDb) )
                return;

            if( !exportSqlite_parameter(dir,pg,pg_step,query,deviceDb) )
                return;

            if( !exportSqlite_action(dir,pg,pg_step,query,deviceDb,actionDescDb) )
                return;

            if( !exportSqlite_device(dir,query) )
                return;

            if( !exportSqlite_statusDesc(dir,query,statusDescDb) )
                return;

            if( !exportSqlite_discreteDesc(dir,query,discreteDescDb) )
                return;

            if( !exportSqlite_remoteCtlDesc(dir,query,remoteCtlDescDb) )
                return;

            if( !exportSqlite_actionDesc(dir,query,actionDescDb) )
                return;

            if( !exportSqlite_logicDevice(dir,query))
                return;

            if( !exportSqlite_logicStatus(dir,pg,pg_step,query,logicDb))
                return;

            if( !exportSqlite_logicDiscrete(dir,pg,pg_step,query,logicDb))
                return;

            if( !exportSqlite_logicMeasure(dir,pg,pg_step,query,logicDb))
                return;

            if( !exportSqlite_logicCumulant(dir,pg,pg_step,query,logicDb))
                return;

            if( !exportSqlite_logicRemoteCtl(dir,pg,pg_step,query,logicDb))
                return;

            if( !exportSqlite_logicParameter(dir,pg,pg_step,query,logicDb))
                return;

            if( !exportSqlite_logicAction(dir,pg,pg_step,query,logicDb))
                return;
        }
    }
}

void UiScadaCfgTool::addDevice(){
    if(ui->tabWidget_type->currentIndex()==0 ){
        // 增加物理设备
        UiDeviceInfo* ud = new UiDeviceInfo;
        m_devices.append(ud);
        ui->tabWidget_devices->addTab(ud,QString::number(m_devices.size()).append("#"));

        connect(ud,SIGNAL(descChanged()),this,SLOT(deviceDescChanged()));

        connect(ud,SIGNAL(statusFileChanged(QString,QString)),this,SLOT(deviceStatusFileChanged(QString,QString)));
        connect(ud,SIGNAL(discreteFileChanged(QString,QString)),this,SLOT(deviceDiscreteFileChanged(QString,QString)));
        connect(ud,SIGNAL(measureFileChanged(QString,QString)),this,SLOT(deviceMeasureFileChanged(QString,QString)));
        connect(ud,SIGNAL(cumulantFileChanged(QString,QString)),this,SLOT(deviceCumulantFileChanged(QString,QString)));
        connect(ud,SIGNAL(remoteCtlFileChanged(QString,QString)),this,SLOT(deviceRemoteCtlFileChanged(QString,QString)));
        connect(ud,SIGNAL(parameterFileChanged(QString,QString)),this,SLOT(deviceParameterFileChanged(QString,QString)));
        connect(ud,SIGNAL(actionFileChanged(QString,QString)),this,SLOT(deviceActionFileChanged(QString,QString)));

        ui->tabWidget_devices->setCurrentIndex( ui->tabWidget_devices->count()-1);
    }else{
        // 增加逻辑设备
        UiLogicDevice* ud = new UiLogicDevice;
        m_logicDevices.append(ud);
        ui->tabWidget_logics->addTab(ud,QString::number(m_logicDevices.size()).append("#"));

        connect(ud,SIGNAL(descChanged(QString)),this,SLOT(logicDeviceDescChanged()));

        connect(ud,SIGNAL(statusMapFileChanged(QString,QString)),this,SLOT(logicDeviceStatusFileChanged(QString,QString)));
        connect(ud,SIGNAL(discreteMapFileChanged(QString,QString)),this,SLOT(logicDeviceDiscreteFileChanged(QString,QString)));
        connect(ud,SIGNAL(measureMapFileChanged(QString,QString)),this,SLOT(logicDeviceMeasureFileChanged(QString,QString)));
        connect(ud,SIGNAL(cumulantMapFileChanged(QString,QString)),this,SLOT(logicDeviceCumulantFileChanged(QString,QString)));
        connect(ud,SIGNAL(remoteCtlMapFileChanged(QString,QString)),this,SLOT(logicDeviceRemoteCtlFileChanged(QString,QString)));
        connect(ud,SIGNAL(parameterMapFileChanged(QString,QString)),this,SLOT(logicDeviceParameterFileChanged(QString,QString)));
        connect(ud,SIGNAL(actionMapFileChanged(QString,QString)),this,SLOT(logicDeviceActionFileChanged(QString,QString)));

        ui->tabWidget_logics->setCurrentIndex( ui->tabWidget_logics->count()-1);
    }

}

void UiScadaCfgTool::delDevice(){
    if( ui->tabWidget_type->currentIndex()==0 ){
        // 物理设备
        int index = ui->tabWidget_devices->currentIndex();
        if( index>0 ){
            ui->tabWidget_devices->removeTab(index);
            m_devices.removeAt(index);
        }
    }else{
        // 逻辑设备
        int index = ui->tabWidget_logics->currentIndex();
        if( index>0 ){
            ui->tabWidget_logics->removeTab(index);
            m_logicDevices.removeAt(index);
        }
    }
}

void UiScadaCfgTool::delDevice( int index ){
    if( ui->tabWidget_type->currentIndex()==0 ){
        // 物理设备
        if( index<0 )
            return;
        ui->tabWidget_devices->removeTab(index);
        m_devices.removeAt(index);
    }else{
        // 逻辑设备
        if( index<0 )
            return;
        ui->tabWidget_logics->removeTab(index);
        m_logicDevices.removeAt(index);
    }

}

void UiScadaCfgTool::cloneDevice(){
    if( ui->tabWidget_type->currentIndex()==0 ){
        // 物理设备
        int index = ui->tabWidget_devices->currentIndex();
        if( index<0 ){
            QMessageBox::warning(this,tr("Attention"),tr("Must select a device"));
        }else{
            addDevice();

            UiDeviceInfo* old = m_devices.at(index);
            UiDeviceInfo* now = m_devices.last();

            now->setName( old->getName() );
            now->setDesc( old->getDesc() );
            now->setStatusCfgFileName( old->getStatusCfgFileName(true) );
            now->setDiscreteCfgFileName( old->getDiscreteCfgFileName(true) );
            now->setMeasureCfgFileName( old->getMeasureCfgFileName(true) );
            now->setCumulantCfgFileName( old->getCumulantCfgFileName(true) );
            now->setRemoteCtlCfgFileName( old->getRemoteCtlCfgFileName(true) );
            now->setParameterCfgFileName( old->getParameterCfgFileName(true) );
            now->setActionCfgFileName( old->getActionCfgFileName(true));
        }
    }else{
        // 逻辑设备
        int index = ui->tabWidget_logics->currentIndex();
        if( index<0 ){
            QMessageBox::warning(this,tr("Attention"),tr("Must select a device"));
        }else{
            addDevice();

            UiLogicDevice* old = m_logicDevices.at(index);
            UiLogicDevice* now = m_logicDevices.last();

            now->setName( old->getName() );
            now->setDesc( old->getDesc() );
            now->setStatusMapFile( old->getStatusMapFile(true) );
            now->setDiscreteMapFile( old->getDiscreteMapFile(true) );
            now->setMeasureMapFile( old->getMeasureMapFile(true) );
            now->setCumulantMapFile( old->getCumulantMapFile(true) );
            now->setRemoteCtlMapFile(old->getRemoteCtlMapFile(true) );
            now->setParameterMapFile(old->getParameterMapFile(true) );
            now->setActionMapFile(old->getActionMapFile(true));
        }
    }

}

void UiScadaCfgTool::help(){
    QTextEdit* te = new QTextEdit;
    te->setWindowTitle(tr("Help"));
    te->append( tr("Format of Configurations"));
    te->append("");
    te->append( tr("Status:name,comment,level,desc of off,desc of on,desc of inv off,desc of inv on"));
    te->append( tr("Discrete:name,comment,state1:state2:...:staten"));
    te->append( tr("Measure:name,comment,unit,delta"));
    te->append( tr("Cumulant:name,comment,max code"));
    te->append( tr("Remote Control: name,comment,test,reset,open,close"));
    te->append(tr("Parameter: name,comment"));
    te->append(QString("Build on ").append(__DATE__));

    te->show();
}

void UiScadaCfgTool::deviceDescChanged(){
    int index = ui->tabWidget_devices->currentIndex();

    const UiDeviceInfo* device = dynamic_cast<const UiDeviceInfo*>(ui->tabWidget_devices->widget(index));
    ui->tabWidget_devices->setTabText( index, QString::number(index+1)+device->getDesc() );
}

void UiScadaCfgTool::logicDeviceDescChanged(){
    int index = ui->tabWidget_logics->currentIndex();

    const UiLogicDevice* device = dynamic_cast<const UiLogicDevice*>(ui->tabWidget_logics->widget(index));
    ui->tabWidget_logics->setTabText( index, QString::number(index+1)+device->getDesc() );
}

void UiScadaCfgTool::deviceStatusFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeStatusCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::deviceDiscreteFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeDiscreteCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::deviceMeasureFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeMeasureCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::deviceCumulantFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeCumulantCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::deviceRemoteCtlFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeRemoteCtlCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::deviceParameterFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeParameterCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::deviceActionFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_devices.count();++i ){
        m_devices.at(i)->autoChangeActionCfgFileName(oldFile,newFile);
    }
}

void UiScadaCfgTool::logicDeviceStatusFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeStatusMapFile(oldFile,newFile);
}

void UiScadaCfgTool::logicDeviceDiscreteFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeDiscreteMapFile(oldFile,newFile);
}

void UiScadaCfgTool::logicDeviceMeasureFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeMeasureMapFile(oldFile,newFile);
}

void UiScadaCfgTool::logicDeviceCumulantFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeCumulantMapFile(oldFile,newFile);
}

void UiScadaCfgTool::logicDeviceRemoteCtlFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeRemoteCtlMapFile(oldFile,newFile);
}

void UiScadaCfgTool::logicDeviceParameterFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeParameterMapFile(oldFile,newFile);
}

void UiScadaCfgTool::logicDeviceActionFileChanged(QString oldFile, QString newFile){
    for( int i=0;i<m_logicDevices.count();++i )
        m_logicDevices.at(i)->autoChangeActionMapFile(oldFile,newFile);
}

bool UiScadaCfgTool::exportCheck(){
    if( m_devices.count()<1 ){
        QMessageBox::warning(this,tr("info"),tr("No device"));
        return false;
    }

    // 检测设备名
    CStringDb db;
    for( int i=0;i<m_devices.count();++i ){
        db.findOrAdd(m_devices.at(i)->getName());
        if( db.getDb().count()<=i ){
            QMessageBox::warning(this,tr("info"),tr("Device %1 Has the same name as before").arg(QString::number(i+1)));
            return false;
        }
    }

    // 检测设备名
    CStringDb logicDb;
    for( int i=0;i<m_logicDevices.count();++i ){
        logicDb.findOrAdd(m_logicDevices.at(i)->getName());
        if( logicDb.getDb().count()<=i ){
            QMessageBox::warning(this,tr("info"),tr("Logic Device %1 Has the same name as before").arg(QString::number(i+1)));
            return false;
        }
    }

    if( ui->checkBox_sysInfo->isChecked() ){
        if( db.getDb().contains("sys")){
            QMessageBox::warning(this,tr("info"),tr("产生设备信息已经被勾选，设备不应该有sys"));
            return false;
        }
    }

    return true;
}

int UiScadaCfgTool::getFileLines(const QString &path) const{
    if( path.isEmpty() )
        return 0;

    QFile inFile(path);
    if( !inFile.open(QFile::ReadOnly|QFile::Text) ){
        return -1;
    }

    QTextStream stream(&inFile);
    int rt = 0;
    while( !stream.atEnd() ){
        stream.readLine();
        ++rt;
    }

    return rt;
}

bool UiScadaCfgTool::exportSqlite_createTables(QSqlQuery &query){
    query.exec("DROP TABLE IF EXISTS t_device");
    query.exec("CREATE TABLE t_device (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, no integer(11) NOT NULL UNIQUE, descr varchar(64) NOT NULL, parent integer(11), comment varchar(255), FOREIGN KEY(parent) REFERENCES t_device(id))");

    query.exec("DROP TABLE IF EXISTS t_status_desc");
    query.exec("CREATE TABLE t_status_desc (id INTEGER NOT NULL PRIMARY KEY, no integer(11) NOT NULL UNIQUE, descr varchar(64) NOT NULL, comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_status");
    query.exec("CREATE TABLE t_status (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, device integer(11) NOT NULL, no integer(11) NOT NULL, descr varchar(64) NOT NULL, level integer(5) NOT NULL, desc_invoff integer(11), desc_off integer(11), desc_on integer(11), desc_invon integer(11),store_flag integer(1),gen_timed_flag integer(1),rpt_timed_flag integer(1),comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_discrete_desc");
    query.exec("CREATE TABLE t_discrete_desc (id INTEGER NOT NULL PRIMARY KEY, no integer(11) NOT NULL UNIQUE, descr varchar(64) NOT NULL, comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_discrete");
    query.exec("CREATE TABLE t_discrete (id INTEGER NOT NULL PRIMARY KEY, device integer(11) NOT NULL, no integer(11) NOT NULL, name varchar(64) NOT NULL UNIQUE, descr varchar(64) NOT NULL, desc_start integer(11) NOT NULL, desc_num integer(11) NOT NULL,store_flag integer(1),gen_timed_flag integer(1),rpt_timed_flag integer(1), comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_measure");
    query.exec("CREATE TABLE t_measure (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, device integer(11) NOT NULL, no integer(11) NOT NULL, descr varchar(64) NOT NULL, unit varchar(64), value_base float(10) NOT NULL, value_coef float(10) NOT NULL, delta float(10) NOT NULL,store_flag integer(1),gen_timed_flag integer(1),rpt_timed_flag integer(1), comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_cumulant");
    query.exec("CREATE TABLE t_cumulant (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, device integer(11) NOT NULL, no integer(11) NOT NULL, descr varchar(64) NOT NULL, max integer(11) NOT NULL, delta integer(11) NOT NULL, coef float(10) NOT NULL,store_flag integer(1),gen_timed_flag integer(1),rpt_timed_flag integer(1),comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_remote_ctl_desc");
    query.exec("CREATE TABLE t_remote_ctl_desc (id INTEGER NOT NULL PRIMARY KEY, no integer(11) NOT NULL UNIQUE, descr varchar(64) NOT NULL, comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_remote_ctl");
    query.exec("CREATE TABLE t_remote_ctl (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL, device integer(11) NOT NULL, no integer(11) NOT NULL, descr varchar(64) NOT NULL, desc_preopen integer(11), desc_preclose integer(11), desc_close integer(11), desc_open integer(11), comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_parameter");
    query.exec("CREATE TABLE t_parameter (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, device integer(11) NOT NULL, no integer(11) NOT NULL, descr varchar(64) NOT NULL, comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_action_desc");
    query.exec("CREATE TABLE t_action_desc (id INTEGER NOT NULL PRIMARY KEY, no integer(11) NOT NULL UNIQUE, descr varchar(64) NOT NULL, comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_action");
    query.exec("CREATE TABLE t_action (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, device integer(11) NOT NULL, no integer(11) NOT NULL, descr varchar(64) NOT NULL, level integer(11) NOT NULL, desc_invoff integer(11), desc_off integer(11), desc_on integer(11), desc_invon integer(11),store_flag integer(1),rpt_timed_flag integer(1), comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_logic_device");
    query.exec("CREATE TABLE t_logic_device (id INTEGER NOT NULL PRIMARY KEY, name varchar(64) NOT NULL UNIQUE, no integer(11) NOT NULL, descr varchar(64) NOT NULL, comment varchar(255))");

    query.exec("DROP TABLE IF EXISTS t_logic_status");
    query.exec("CREATE TABLE t_logic_status (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, status integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    query.exec("DROP TABLE IF EXISTS t_logic_discrete");
    query.exec("CREATE TABLE t_logic_discrete (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, discrete integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    query.exec("DROP TABLE IF EXISTS t_logic_measure");
    query.exec("CREATE TABLE t_logic_measure (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, measure integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    query.exec("DROP TABLE IF EXISTS t_logic_cumulant");
    query.exec("CREATE TABLE t_logic_cumulant (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, cumulant integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    query.exec("DROP TABLE IF EXISTS t_logic_remotectl");
    query.exec("CREATE TABLE t_logic_remotectl (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, remote_ctl integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    query.exec("DROP TABLE IF EXISTS t_logic_parameter");
    query.exec("CREATE TABLE t_logic_parameter (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, parameter integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    query.exec("DROP TABLE IF EXISTS t_logic_action");
    query.exec("CREATE TABLE t_logic_action (logic_device integer(11) NOT NULL, no integer(11) NOT NULL, action integer(11) NOT NULL, PRIMARY KEY (logic_device, no))");

    return true;
}

/**
 * @brief 导出状态量
 * @param dir
 * @param pg
 * @param pg_step
 * @param query
 * @param deviceDb
 * @param statusDescDb
 * @return
 */
bool UiScadaCfgTool::exportSqlite_status( const QString& dir,QProgressDialog& pg,int& pg_step,QSqlQuery& query,CStringDb& deviceDb,CStringDb& statusDescDb ){
    QFile outFile;

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();

    QFile csvFile;
    QFile logicMapFile;

    pg.setLabelText( QString::fromUtf8("Gen Statuses"));

    // 导出状态量 =============================================
    outFile.setFileName(dir+"sqlite_init_status.sql");
    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("状态量.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射_状态量.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream outStream(&outFile);
    outStream.setCodec("UTF-8");

    QTextStream outCsv(&csvFile);
    outCsv.setCodec("UTF-8");

    QTextStream outLogicMap(&logicMapFile);
    outLogicMap.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sql = "";
    sqlStream     <<"DELETE FROM t_status";
    query.exec(sql);

    outStream << sql <<";\n\n";

    if( csv ){
        outCsv <<QString::fromUtf8("#名称;描述;备注;级别;分状态;合状态;无效分状态;无效合状态;是否存盘;是否产生时标数据;是否上报时标数据\n");
    }

    if( logicMap )
        outLogicMap <<QString::fromUtf8("#设备名;状态量名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getStatusCfgFileName();
        if( fileName.isEmpty() )
            continue;

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的状态配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        if( csv ){
            outCsv <<'\n';
        }

        if( logicMap )
            outLogicMap <<'\n';

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=11  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的状态量配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_status(id, name,device, no, descr,comment, level, desc_off, desc_on,desc_invoff,desc_invon,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<",'"
                    <<m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"',"
                    <<deviceId<<","
                    <<no++<<",'"
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"',"
                    <<items.at(3).toInt()<<","
                    <<statusDescDb.findOrAdd(items.at(4).trimmed())+1<<","
                    <<statusDescDb.findOrAdd(items.at(5).trimmed())+1<<","
                    <<statusDescDb.findOrAdd(items.at(6).trimmed())+1<<","
                    <<statusDescDb.findOrAdd(items.at(7).trimmed())+1<<","
                    <<items.at(8).toInt()<<","
                    <<items.at(9).toInt()<<","
                    <<items.at(10).toInt()<<")";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()<<';'
                     <<items.at(3).trimmed()<<';'
                     <<items.at(4).trimmed()<<';'
                     <<items.at(5).trimmed()<<';'
                     <<items.at(6).trimmed()<<';'
                     <<items.at(7).trimmed()<<';'
                     <<items.at(8).trimmed()<<';'
                    <<items.at(9).trimmed()<<';'
                     <<items.at(10).trimmed()
                    <<'\n';
            }

            if( logicMap ){
                outLogicMap<<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
            }
        }

        m_devices.at(i)->setStatusNum(no-1);
    }

    // 导出系统状态
    if( ui->checkBox_sysInfo->isChecked() ){
        int deviceId = deviceDb.findOrAdd("sys")+1;

        if( csv ){
            outCsv <<'\n';
        }

        if( logicMap )
            outLogicMap<<'\n';

        int no = 1;

        for( int i=0;i<m_devices.count();++i ){
            sql = "";
            sqlStream<<"INSERT INTO t_status(id, name,device, no, descr,comment, level, desc_off, desc_on,desc_invoff,desc_invon,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++
                    <<",'_"<<m_devices.at(i)->getName()<<".Online',"
                    <<deviceId<<","
                    <<no++
                    <<QString::fromUtf8(",'_%1 是否在线','自动生成',1,").arg(m_devices.at(i)->getDesc())
                    <<statusDescDb.findOrAdd(QString::fromUtf8("离线"))+1<<','
                    <<statusDescDb.findOrAdd(QString::fromUtf8("在线"))+1<<','
                    <<statusDescDb.findOrAdd(QString::fromUtf8("无效分状态"))+1<<','
                    <<statusDescDb.findOrAdd(QString::fromUtf8("无效合状态"))+1<<",1,1,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName()<<".Online;_"
                     <<m_devices.at(i)->getDesc()<<QString::fromUtf8(" 是否在线;;1;离线;在线;无效分状态;无效合状态;1;1;1\n");
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".Online\n";
        }
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_discrete( const QString& dir,QProgressDialog& pg,int& pg_step,QSqlQuery& query,CStringDb& deviceDb,CStringListDb& discreteDescDb ){
    // 导出离散量 =============================================
    QFile outFile;

    pg.setLabelText( QString::fromUtf8("Gen Discrete") );

    outFile.setFileName(dir+"sqlite_init_discrete.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sql = "";
    sqlStream <<"DELETE FROM t_discrete";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();
    QFile csvFile;
    QFile logicMapFile;

    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("离散量.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射-离散量.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    QTextStream outCsv(&csvFile);
    QTextStream outLogicMap(&logicMapFile);
    outCsv.setCodec("UTF-8");
    outLogicMap.setCodec("UTF-8");

    if( csv )
        outCsv <<QString::fromUtf8("#名称;描述;备注;状态1:状态2:...:状态n;是否存盘;是否产生时标数据;是否上报时标数据\n");

    if( logicMap )
        outLogicMap <<QString::fromUtf8("#设备名;离散量名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getDiscreteCfgFileName();

        if( fileName.isEmpty() ){
            continue;
        }

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的离散量配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap <<'\n';

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");
        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();
            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");
            if( items.count()!=7  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的离散量配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            QStringList descs = items.at(3).split(':');

            sql = "";
            sqlStream<<"INSERT INTO t_discrete(id, name, device, no, descr, comment,desc_start, desc_num,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<",'"
                    <<m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"',"
                    <<deviceId<<","
                    <<no++<<",'"                    
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"',"
                    <<discreteDescDb.findOrAdd(descs)+1<<","
                    <<descs.count()<<","
                    <<items.at(4).trimmed()<<","
                    <<items.at(5).trimmed()<<","
                    <<items.at(6).trimmed()
                    <<")";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()<<';'
                     <<items.at(3).trimmed()<<';'
                     <<items.at(4).trimmed()<<';'
                     <<items.at(5).trimmed()<<';'
                     <<items.at(6).trimmed()
                    <<'\n';
            }
            if( logicMap ){
                outLogicMap<<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
            }
        }

        m_devices.at(i)->setDiscreteNum(no-1);
    }

    // 导出设备离散量信息
    if( ui->checkBox_sysInfo->isChecked() ){
        int deviceId = deviceDb.findOrAdd("sys")+1;

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap <<'\n';

        int no = 1;

        QStringList descs = QString::fromUtf8("系统初始化:通信采集连接中:通信采集已连接:通信采集连接失败:通信采集断开连接:本地采集正在运行:本地采集未运行").split(':');
        int descIdx = discreteDescDb.findOrAdd(descs)+1;

        for( int i=0;i<m_devices.count();++i ){
            sql = "";
            sqlStream<<"INSERT INTO t_discrete(id, name, device, no, descr, comment,desc_start, desc_num,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".State',"
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 状态','',")
                    <<descIdx<<","
                    <<descs.count()<<",1,1,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".State"<<';'
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 状态;自动生成;系统初始化:通信采集连接中:通信采集已连接:通信采集连接失败:通信采集断开连接:本地采集正在运行:本地采集未运行;1;1;1\n");
            }
            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".State\n";
        }
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_measure( const QString& dir,QProgressDialog& pg,int& pg_step,QSqlQuery& query,CStringDb& deviceDb ){
    pg.setLabelText( QString::fromUtf8("Gen Measures"));

    // 导出测量量 =============================================
    QFile outFile(dir+"sqlite_init_measure.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_measure";
    query.exec(sql);

    outStream <<sql<<";\n\n";

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();
    bool csvAjt = ui->checkBox_autoAdjust->isChecked();
    QFile csvFile;
    QFile logicMapFile;

    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("测量量.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射-测量量.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    QTextStream outCsv(&csvFile);
    QTextStream outLogicMap(&logicMapFile);
    outCsv.setCodec("UTF-8");
    outLogicMap.setCodec("UTF-8");

    if( csv )
        outCsv <<QString::fromUtf8("#名称;描述;备注;单位;变化限值;基数;系数;是否存盘;是否产生时标数据;是否上报时标数据\n");
    if( logicMap )
        outLogicMap<<QString::fromUtf8("#设备名;测量量名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getMeasureCfgFileName();

        if( fileName.isEmpty() )
            continue;

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的测量量配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap <<'\n';

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;

            pg.setValue(pg_step++);

            QString line = inStream.readLine().trimmed();
            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");
            if( items.count()!=10  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的测量量配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream <<"INSERT INTO t_measure(id, device, no, name, descr,comment, unit, delta,value_base,value_coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++<<",'"
                    <<m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"','"
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"','"
                    <<items.at(3).trimmed()<<"',"
                    <<items.at(4).toFloat()<<','
                    <<items.at(5).toFloat()<<','
                    <<items.at(6).toFloat()<<','
                    <<items.at(7).trimmed()<<','
                    <<items.at(8).trimmed()<<','
                    <<items.at(9).trimmed()
                 <<")";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()<<';'
                     <<items.at(3).trimmed()<<';'
                     <<items.at(4).trimmed()<<';';
                if( csvAjt )
                    outCsv <<"0;1";
                else
                    outCsv <<items.at(5).trimmed()<<';'<<items.at(6).trimmed();

                outCsv<<';'
                    <<items.at(7).trimmed()<<';'
                    <<items.at(8).trimmed()<<';'
                    <<items.at(9).trimmed()
                    <<'\n';
            }

            if( logicMap )
                outLogicMap<<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
        }

        m_devices.at(i)->setMeasureNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_cumulant(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &deviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Cumulants"));

    // 导出累计量 =============================================

    QFile outFile(dir+"sqlite_init_cumulant.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_cumulant";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();
    QFile csvFile;
    QFile logicMapFile;

    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("累计量.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射-累计量.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    QTextStream outCsv(&csvFile);
    QTextStream outLogicMap(&logicMapFile);
    outCsv.setCodec("UTF-8");
    outLogicMap.setCodec("UTF-8");

    if( csv )
        outCsv <<QString::fromUtf8("#名称;描述;备注;满码值;变化限值;系数;是否存盘;是否产生时标数据;是否上报时标数据\n");
    if( logicMap )
        outLogicMap<<QString::fromUtf8("#设备名;累计量名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getCumulantCfgFileName();

        if( fileName.isEmpty() )
            continue;

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的累计量配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        if( csv )
            outCsv <<'\n';

        if( logicMap )
            outLogicMap <<'\n';

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;

            pg.setValue(pg_step++);

            QString line = inStream.readLine().trimmed();
            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");
            if( items.count()!=9 ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的累计量配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++<<",'"
                    <<m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"','"
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"',"
                    <<items.at(3).toInt()<<','
                    <<items.at(4).toInt()<<','
                    <<items.at(5).toFloat()<<','
                    <<items.at(6).trimmed() <<','
                    <<items.at(7).trimmed() <<','
                    <<items.at(8).trimmed()
                    <<")";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()<<';'
                     <<items.at(3).trimmed()<<';'
                     <<items.at(4).trimmed()<<';'
                     << items.at(5).trimmed()<<';'
                     <<items.at(6).trimmed() <<';'
                     <<items.at(7).trimmed() <<';'
                     <<items.at(8).trimmed()
                     <<'\n';
            }

            if( logicMap )
                outLogicMap<<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
        }
        m_devices.at(i)->setCumulantNum(no-1);
    }

    // 导出设备累计量信息
    if( ui->checkBox_sysInfo->isChecked() ){
        int deviceId = deviceDb.findOrAdd("sys")+1;

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap <<'\n';

        int no = 1;

        for( int i=0;i<m_devices.count();++i ){
            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".RxCnt','_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 接收流量计数','',")
                   <<0xFFFFFFFFu<<",1,1,1,0,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".RxCnt;"
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 接收流量计数;自动生成;")<<0xFFFFFFFF<<";1;1;1;0;1\n";
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".RxCnt\n";

            //====
            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".TxCnt','_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 发送流量计数','',")
                   <<0xFFFFFFFFu<<",1,1,1,0,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".TxCnt;"
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 发送流量计数;自动生成;")<<0xFFFFFFFF<<";1;1;1;0;1\n";
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".TxCnt\n";

            //====
            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".StartRx','_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 开始接收时刻','',")
                   <<0xFFFFFFFFu<<",1,1,1,0,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".StartRx;"
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 开始接收时刻;自动生成;")<<0xFFFFFFFF<<";1;1;1;0;1\n";
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".StartRx\n";

            //====
            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".StartTx','_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 开始发送时刻','',")
                   <<0xFFFFFFFFu<<",1,1,1,0,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".StartTx;"
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 开始发送时刻;自动生成;")<<0xFFFFFFFF<<";1;1;1;0;1\n";
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".StartTx\n";

            //====
            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".lastRx','_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 最后接收时刻','',")
                   <<0xFFFFFFFFu<<",1,1,1,0,1)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".lastRx;"
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 最后接收时刻;自动生成;")<<0xFFFFFFFF<<";1;1;1;0;1\n";
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".lastRx\n";

            //====
            sql = "";
            sqlStream<<"INSERT INTO t_cumulant(id, device, no, name, descr,comment, max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++
                    <<",'_"<<m_devices.at(i)->getName().trimmed()<<".lastTx','_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 最后发送时刻','',")
                   <<0xFFFFFFFFu<<",1,1,1,0,0)";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<"_"<<m_devices.at(i)->getName().trimmed()<<".lastTx;"
                     <<"_"<<m_devices.at(i)->getDesc().trimmed()<<QString::fromUtf8(" 最后发送时刻;自动生成;")<<0xFFFFFFFF<<";1;1;1;0;1\n";
            }

            if( logicMap )
                outLogicMap<<";"<<'_'<<m_devices.at(i)->getName()<<".lastTx\n";
        }
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_remoteCtl(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &deviceDb, CStringDb &remoteCtlDescDb){
    pg.setLabelText( QString::fromUtf8("Gen Remote Controls"));

    // 导出远控 =============================================
    QFile outFile(dir+"sqlite_init_remotectl.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_remote_ctl";
    query.exec(sql);

    outStream <<sql<<";\n\n";

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();
    QFile csvFile;
    QFile logicMapFile;

    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("远控.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射-远控.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    QTextStream outCsv(&csvFile);
    QTextStream outLogicMap(&logicMapFile);
    outCsv.setCodec("UTF-8");
    outLogicMap.setCodec("UTF-8");

    if( csv )
        outCsv <<QString::fromUtf8("#名称;描述;备注;预控分;预控合;控分;控合\n");
    if( logicMap )
        outLogicMap<<QString::fromUtf8("#设备名;远控名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getRemoteCtlCfgFileName();

        if( fileName.isEmpty() )
            continue;

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的远控配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap<<'\n';

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;

            pg.setValue(pg_step++);

            QString line = inStream.readLine().trimmed();
            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");
            if( items.count()!=7  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的远控配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_remote_ctl(id, device, no, name, descr, comment,desc_preopen,desc_preclose,desc_open,desc_close ) VALUES ("
                    << id++<<","
                    << deviceId<<","
                    <<no++<<",'"
                    <<m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"','"
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"',"
                    <<remoteCtlDescDb.findOrAdd(items.at(3).trimmed())+1<<","
                    <<remoteCtlDescDb.findOrAdd(items.at(4).trimmed())+1<<","
                    <<remoteCtlDescDb.findOrAdd(items.at(5).trimmed())+1<<","
                    <<remoteCtlDescDb.findOrAdd(items.at(6).trimmed())+1
                    <<")";
            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql
                    <<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()<<';'
                     <<items.at(3).trimmed()<<';'
                     <<items.at(4).trimmed()<<';'
                     <<items.at(5).trimmed()<<';'
                     <<items.at(6).trimmed()
                    <<'\n';
            }

            if( logicMap )
                outLogicMap<<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
        }

        m_devices.at(i)->setRemoteCtlNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_parameter(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &deviceDb ){
    pg.setLabelText( QString::fromUtf8("Gen Parameters"));

    // 导出参数 =============================================
    QFile outFile(dir+"sqlite_init_parameter.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_parameter";
    query.exec(sql);

    outStream <<sql<<";\n\n";

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();
    QFile csvFile;
    QFile logicMapFile;

    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("参数.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射-参数.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    QTextStream outCsv(&csvFile);
    QTextStream outLogicMap(&logicMapFile);
    outCsv.setCodec("UTF-8");
    outLogicMap.setCodec("UTF-8");

    if( csv )
        outCsv <<QString::fromUtf8("#名称;描述;备注\n");
    if( logicMap )
        outLogicMap<<QString::fromUtf8("#设备名;参数名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getParameterCfgFileName();

        if( fileName.isEmpty() )
            continue;

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的参数配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap <<'\n';

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;

            pg.setValue(pg_step++);

            QString line = inStream.readLine().trimmed();
            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");
            if( items.count()!=3  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的参数配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_parameter(id, device, no, name, descr,comment ) VALUES ("
                    << id++<<","
                    << deviceId<<","
                    << no++<<",'"
                    << m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"','"
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"'"
                    <<")";
            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream<<sql<<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()
                    <<'\n';
            }

            if( logicMap )
                outLogicMap <<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
        }

        m_devices.at(i)->setParameterNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_action(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &deviceDb, CStringDb &actionDescDb){
    pg.setLabelText( QString::fromUtf8("Gen Actions"));

    // 导出动作 =============================================

    QFile outFile(dir+"sqlite_init_action.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream     <<"DELETE FROM t_action";
    query.exec(sql);

    outStream << sql <<";\n\n";

    bool csv = ui->checkBox_genCsv->isChecked();
    bool logicMap = ui->checkBox_mapAll->isChecked();
    QFile csvFile;
    QFile logicMapFile;

    if( csv ){
        csvFile.setFileName(dir+QString::fromUtf8("动作.csv"));
        if( !csvFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(csvFile.fileName()));
            return false;
        }
    }

    if( logicMap ){
        logicMapFile.setFileName(dir+QString::fromUtf8("映射-动作.csv"));
        if( !logicMapFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(logicMapFile.fileName()));
            return false;
        }
    }

    QTextStream outCsv(&csvFile);
    QTextStream outLogicMap(&logicMapFile);
    outCsv.setCodec("UTF-8");
    outLogicMap.setCodec("UTF-8");

    if( csv )
        outCsv <<QString::fromUtf8("#名称;描述;备注;级别;分状态;合状态;无效分状态;无效合状态;是否存盘;是否上报时标数据\n");
    if( logicMap )
        outLogicMap <<QString::fromUtf8("#设备名;动作名\n");

    int id = 1;

    for( int i=0;i<m_devices.count();++i ){
        QString fileName = m_devices.at(i)->getActionCfgFileName();
        if( fileName.isEmpty() )
            continue;

        int deviceId = deviceDb.findOrAdd( m_devices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个设备的动作配置文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        if( csv )
            outCsv <<'\n';
        if( logicMap )
            outLogicMap <<'\n';

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=10  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("设备%1的动作量配置文件%2的第%3行不正确").arg( m_devices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_action(id, device, no, name,descr,comment, level, desc_off, desc_on,desc_invoff,desc_invon,store_flag,rpt_timed_flag) VALUES ("
                    << id++<<","
                    <<deviceId<<","
                    <<no++<<",'"
                    <<m_devices.at(i)->getName().trimmed()+"."+items.at(0).trimmed()<<"','"
                    <<items.at(1).trimmed()<<"','"
                    <<items.at(2).trimmed()<<"',"
                    <<items.at(3).toInt()<<","
                    <<actionDescDb.findOrAdd(items.at(4).trimmed())+1<<","
                    <<actionDescDb.findOrAdd(items.at(5).trimmed())+1<<","
                    <<actionDescDb.findOrAdd(items.at(6).trimmed())+1<<","
                    <<actionDescDb.findOrAdd(items.at(7).trimmed())+1<<","
                    <<items.at(8).trimmed()<<','
                    <<items.at(9).trimmed()
                    <<")";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";

            if( csv ){
                outCsv<<m_devices.at(i)->getName().trimmed()+'.'+items.at(0).trimmed()<<';'
                     <<m_devices.at(i)->getDesc().trimmed()+' '+items.at(1).trimmed()<<';'
                     <<items.at(2).trimmed()<<';'
                     <<items.at(3).trimmed()<<';'
                     <<items.at(4).trimmed()<<';'
                     <<items.at(5).trimmed()<<';'
                     <<items.at(6).trimmed()<<';'
                     <<items.at(7).trimmed()<<';'
                     <<items.at(8).trimmed()<<';'
                     <<items.at(9).trimmed()
                    <<'\n';
            }

            if( logicMap )
                outLogicMap <<m_devices.at(i)->getName()<<';'<<items.at(0)<<'\n';
        }

        m_devices.at(i)->setActionNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_device(const QString &dir, QSqlQuery &query ){
    // 导出设备信息
   QFile outFile(dir+"sqlite_init_device.sql");
   if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
       QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
       return false;
   }

   QTextStream  outStream(&outFile);
   outStream.setCodec("UTF-8");

   QString sql;
   QTextStream sqlStream(&sql);
   sqlStream.setCodec("UTF-8");

   sqlStream <<"DELETE FROM t_device";
   query.exec(sql);

   outStream <<sql<<";\n\n";

   for( int i=0;i<m_devices.count();++i ){
       sql = "";
       sqlStream<< "INSERT INTO t_device(id, no, name, descr) VALUES ("
                   <<i+1<<","
                   <<i+1<<",'"
                   << m_devices.at(i)->getName().trimmed() <<"','"
                   << m_devices.at(i)->getDesc().trimmed()
                   <<"')";
       if( ui->checkBox_genSqlite->isChecked() ){
           if( !query.exec(sql) ){
               if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                    QMessageBox::Cancel,QMessageBox::Abort) )
                   return false;
           }
       }

       outStream <<sql<<";\n";
   }

   if( ui->checkBox_sysInfo->isChecked() ){
       sql = "";
       sqlStream<< "INSERT INTO t_device(id, no, name, descr) VALUES ("
                   <<m_devices.count()+1<<","
                   <<m_devices.count()+1
                   <<QString::fromUtf8(",'sys','系统信息')");
       if( ui->checkBox_genSqlite->isChecked() ){
           if( !query.exec(sql) ){
               if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                    QMessageBox::Cancel,QMessageBox::Abort) )
                   return false;
           }
       }

       outStream <<sql<<";\n";
   }

   return true;
}

bool UiScadaCfgTool::exportSqlite_statusDesc(const QString &dir, QSqlQuery &query, CStringDb &statusDescDb){
    // 导出状态描述信息
    QFile outFile(dir+"sqlite_init_statusdesc.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_status_desc";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<statusDescDb.getDb().count();++i ){
        sql = "";
        sqlStream<< "INSERT INTO t_status_desc(id, no, descr) VALUES ("<<i+1<<","<<i+1<<",'"<<statusDescDb.getDb().at(i)<<"')";
        if( ui->checkBox_genSqlite->isChecked() ){
            if( !query.exec(sql) ){
                if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                     QMessageBox::Cancel,QMessageBox::Abort) )
                    return false;
            }
        }

        outStream <<sql<<";\n";
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_discreteDesc(const QString &dir, QSqlQuery &query, CStringListDb& discreteDescDb ){
    // 导出离散量描述信息
    QFile outFile(dir+"sqlite_init_discretedesc.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_discrete_desc";
    query.exec(sql);

    outStream <<sql<<";\n\n";

    for( int i=0;i<discreteDescDb.getDb().count();++i ){
        sql = "";
        sqlStream<< "INSERT INTO t_discrete_desc(id, no, descr) VALUES ("<<i+1<<","<<i+1<<",'"<<discreteDescDb.getDb().at(i)<<"')";
        if( ui->checkBox_genSqlite->isChecked() && !query.exec(sql) )
            qDebug("%s:%s",query.lastError().text().toStdString().c_str(),sql.toStdString().c_str());

        outStream <<sql<<";\n";
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_remoteCtlDesc(const QString &dir, QSqlQuery &query, CStringDb &remoteCtlDescDb ){
    // 导出远控描述信息
    QFile outFile(dir+"sqlite_init_remotectldesc.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_remote_ctl_desc";
    query.exec(sql);
    outStream <<sql<<";\n\n";

    for( int i=0;i<remoteCtlDescDb.getDb().count();++i ){
        sql = "";
        sqlStream<< "INSERT INTO t_remote_ctl_desc(id, no, descr) VALUES ("<<i+1<<","<<i+1<<",'"<<remoteCtlDescDb.getDb().at(i)<<"')";
        if( ui->checkBox_genSqlite->isChecked() ){
            if( !query.exec(sql) ){
                if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                     QMessageBox::Cancel,QMessageBox::Abort) )
                    return false;
            }
        }

        outStream <<sql<<";\n";
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_actionDesc(const QString &dir, QSqlQuery &query, CStringDb &actionDescDb){
    // 导出动作描述信息
    QFile outFile(dir+"sqlite_init_actiondesc.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_action_desc";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<actionDescDb.getDb().count();++i ){
        sql = "";
        sqlStream<< "INSERT INTO t_action_desc(id, no, descr) VALUES ("<<i+1<<","<<i+1<<",'"<<actionDescDb.getDb().at(i)<<"')";
        if( ui->checkBox_genSqlite->isChecked() && !query.exec(sql) )
            qDebug("%s:%s",query.lastError().text().toStdString().c_str(),sql.toStdString().c_str());
        outStream <<sql<<";\n";
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicStatus(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Statuses"));

    QFile outFile(dir+"sqlite_init_logicstatus.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_status";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getStatusMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的状态量映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的状态映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_status(logic_device, no, status) select "
                    <<deviceId<<","
                    <<no++<<",id from t_status where name='";
            if( !items.at(0).isEmpty() )
                sqlStream <<items.at(0)<<".";
            sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setStatusNum(no-1);
    }

    return true;

}

bool UiScadaCfgTool::exportSqlite_logicDiscrete(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Discretes"));

    QFile outFile(dir+"sqlite_init_logicdiscrete.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_discrete";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getDiscreteMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的离散量映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的离散量映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty()  && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_discrete(logic_device, no, discrete) select "
                    <<deviceId<<","
                    <<no++<<",id from t_discrete where name='";
            if(!items.at(0).isEmpty() )
                sqlStream <<items.at(0)<<".";
            sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setDiscreteNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicMeasure(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Measures"));

    QFile outFile(dir+"sqlite_init_logicmeasure.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_measure";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getMeasureMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的测量量映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的测量量映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_measure(logic_device, no, measure) select "
                    <<deviceId<<","
                    <<no++<<",id from t_measure where name='";
              if(!items.at(0).isEmpty() )
                  sqlStream <<items.at(0)<<".";
              sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setMeasureNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicCumulant(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Cumulants"));

    QFile outFile(dir+"sqlite_init_logiccumulant.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_cumulant";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getCumulantMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的累计量映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的累计量映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_cumulant(logic_device, no, cumulant) select "
                    <<deviceId<<","
                    <<no++<<",id from t_cumulant where name='";
            if(!items.at(0).isEmpty() )
                sqlStream <<items.at(0)<<".";
            sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setCumulantNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicRemoteCtl(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Remote Controls"));

    QFile outFile(dir+"sqlite_init_logicremotectl.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_remotectl";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getRemoteCtlMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的远控映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的远控映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_remotectl(logic_device, no, remote_ctl) select "
                    <<deviceId<<","
                    <<no++<<",id from t_remote_ctl where name='";
            if(!items.at(0).isEmpty() )
                sqlStream <<items.at(0)<<".";
            sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setRemoteCtlNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicParameter(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Parameters"));

    QFile outFile(dir+"sqlite_init_logicparameter.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_parameter";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getParameterMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的参数映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的参数映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_parameter(logic_device, no, parameter) select "
                    <<deviceId<<","
                    <<no++<<",id from t_parameter where name='";
            if(!items.at(0).isEmpty() )
                sqlStream <<items.at(0)<<".";
            sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setParameterNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicAction(const QString &dir, QProgressDialog &pg, int &pg_step, QSqlQuery &query, CStringDb &logicDeviceDb){
    pg.setLabelText( QString::fromUtf8("Gen Logic Action"));

    QFile outFile(dir+"sqlite_init_logicaction.sql");
    if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
        QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
        return false;
    }

    QTextStream  outStream(&outFile);
    outStream.setCodec("UTF-8");

    QString sql;
    QTextStream sqlStream(&sql);
    sqlStream.setCodec("UTF-8");

    sqlStream <<"DELETE FROM t_logic_action";
    query.exec(sql);

    outStream<<sql<<";\n\n";

    for( int i=0;i<m_logicDevices.count();++i ){
        QString fileName = m_logicDevices.at(i)->getActionMapFile(false);
        if( fileName.isEmpty() )
            continue;

        int deviceId = logicDeviceDb.findOrAdd( m_logicDevices.at(i)->getName() )+1;
        QFile inFile(fileName);

        if( !inFile.open( QFile::ReadOnly|QFile::Text) ){
            QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("第%1个逻辑设备的动作映射文件%2打开失败").arg( QString::number(i+1)).arg(fileName));
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        int lineNo = 0;
        int no = 1;
        while( !inStream.atEnd() ){
            ++lineNo;
            QString line = inStream.readLine().trimmed();

            pg.setValue(pg_step++);

            if( line.isEmpty() ){
                outStream <<"\n";
                continue;
            }

            if( line.startsWith('#') ){
                outStream <<"\n/* "<<line<<"*/\n";
                continue;
            }

            QStringList items = line.split(";");

            if( items.count()!=2  ){
                QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("逻辑设备%1的参数映射文件%2的第%3行不正确").arg( m_logicDevices.at(i)->getName()).arg(fileName).arg(QString::number(lineNo)));
                return false;
            }

            if( items.at(0).isEmpty() && items.at(1).isEmpty() ){
                outStream <<"\n";
                continue;
            }

            sql = "";
            sqlStream<<"INSERT INTO t_logic_action(logic_device, no, action) select "
                    <<deviceId<<","
                    <<no++<<",id from t_action where name='";
            if(!items.at(0).isEmpty() )
                sqlStream <<items.at(0)<<".";
            sqlStream <<items.at(1)<<"'";

            if( ui->checkBox_genSqlite->isChecked() ){
                if( !query.exec(sql) ){
                    if( QMessageBox::Abort==QMessageBox::warning(this,"error",QString::fromUtf8("执行sql失败:")+query.lastError().text()+"\n"+sql,
                                         QMessageBox::Cancel,QMessageBox::Abort) )
                        return false;
                }
            }

            outStream <<sql<<";\n";
        }

        m_logicDevices.at(i)->setActionNum(no-1);
    }

    return true;
}

bool UiScadaCfgTool::exportSqlite_logicDevice(const QString &dir, QSqlQuery &query ){
    // 导出设备信息
   QFile outFile(dir+"sqlite_init_logicdevice.sql");
   if( !outFile.open(QFile::WriteOnly|QFile::Truncate|QFile::Text) ){
       QMessageBox::warning(this,QString::fromUtf8("错误"),QString::fromUtf8("打开文件%1失败").arg(outFile.fileName()));
       return false;
   }

   QTextStream  outStream(&outFile);
   outStream.setCodec("UTF-8");

   QString sql;
   QTextStream sqlStream(&sql);
   sqlStream.setCodec("UTF-8");

   sqlStream <<"DELETE FROM t_logic_device";
   query.exec(sql);

   outStream <<sql<<";\n\n";

   for( int i=0;i<m_logicDevices.count();++i ){
       sql = "";
       sqlStream<< "INSERT INTO t_logic_device(id, no, name, descr) VALUES ("
                   <<i+1<<","
                   <<i+1<<",'"
                   << m_logicDevices.at(i)->getName() <<"','"
                   << m_logicDevices.at(i)->getDesc()
                   <<"')";
       if( ui->checkBox_genSqlite->isChecked() && !query.exec(sql) )
           qDebug("%s:%s",query.lastError().text().toStdString().c_str(),sql.toStdString().c_str());

       outStream <<sql<<";\n";
   }

   return true;
}
